package com.shardings.sharding.shardingAlgorithm;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.core.parse.old.parser.sql.dml.insert.AbstractInsertParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.CollectionUtils;

import java.util.Collection;

/**
 * 订单表的精确分片算法
 */
public class OrderTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    private final static Logger log = LoggerFactory.getLogger("ShardingSphere-SQL");

    /**
     * 分片方法
     * 如果表名是所有库都唯一，则路由库 = id % 总表数 / 单库表数，路由表=id % 总表数【这种应该均匀一点儿】
     * 如果每个库里表名都一样，则路由库 = id % 总库数，路由表 = id / 总库数 % 单库表数
     *
     * @param availableTargetNames 可用的数据源或表名
     * @param shardingValue        要分片的值
     * @return 分片后得到的数据源或表名
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        for (String name : availableTargetNames) {
            Long value = shardingValue.getValue();
            // 第一个2是总库数，第二个2是单库里的表数。之所有先除2，是可以将分片ID即可变成奇数，也可变成偶数，如22可变成11，12变成6；
            // 再对表数求模时，就可以每个表里都会有数据了。如是不除2，则全都会路由到一张表里
            String suffix = "" + (value / 2 % 2);
            if (name.endsWith(suffix)) {
                // 返回对应的表名
                return name;
            }
        }
        return CollectionUtils.isEmpty(availableTargetNames) ? null : availableTargetNames.toArray()[0].toString();
    }


}
